package drds.global_transaction.resource_manager;

import drds.common.ShouldNeverHappenException;
import drds.global_transaction.api.api.RpcContext;
import drds.global_transaction.api.exception.AbstractExceptionHandler;
import drds.global_transaction.api.exception.GlobalTransactionException;
import drds.global_transaction.api.in_bound_handler.ResourceManagerInboundHandler;
import drds.global_transaction.api.in_bound_handler.TransactionMessageHandler;
import drds.global_transaction.api.message_codec.request_and_response.RequestMessage;
import drds.global_transaction.api.message_codec.request_and_response.ResponseMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.BranchTransactionRequestMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.branch_transaction_end_status_report.branch_transaction_commit_status_report.BranchTransactionCommitRequestMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.branch_transaction_end_status_report.branch_transaction_commit_status_report.BranchTransactionCommitResponseMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.branch_transaction_end_status_report.branch_transaction_rollback_status_report.BranchTransactionRollbackRequestMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.branch_transaction_end_status_report.branch_transaction_rollback_status_report.BranchTransactionRollbackResponseMessage;

public abstract class AbstractResourceManagerHandler extends AbstractExceptionHandler implements ResourceManagerInboundHandler, TransactionMessageHandler
{

	@Override
	public BranchTransactionCommitResponseMessage handle(BranchTransactionCommitRequestMessage branchTransactionCommitRequestMessage)
	{
		BranchTransactionCommitResponseMessage branchTransactionCommitResponseMessage = new BranchTransactionCommitResponseMessage();
		exceptionHandleTemplate(new Callback<BranchTransactionCommitRequestMessage, BranchTransactionCommitResponseMessage>()
		{
			@Override
			public void execute(BranchTransactionCommitRequestMessage branchTransactionCommitRequestMessage, BranchTransactionCommitResponseMessage branchTransactionCommitResponseMessage) throws GlobalTransactionException
			{
				doBranchTransactionCommit(branchTransactionCommitRequestMessage, branchTransactionCommitResponseMessage);
			}
		}, branchTransactionCommitRequestMessage, branchTransactionCommitResponseMessage);
		return branchTransactionCommitResponseMessage;
	}

	protected abstract void doBranchTransactionCommit(BranchTransactionCommitRequestMessage branchTransactionCommitRequestMessage, BranchTransactionCommitResponseMessage branchTransactionCommitResponseMessage) throws GlobalTransactionException;

	@Override
	public BranchTransactionRollbackResponseMessage handle(BranchTransactionRollbackRequestMessage branchTransactionRollbackRequestMessage)
	{
		BranchTransactionRollbackResponseMessage branchTransactionRollbackResponseMessage = new BranchTransactionRollbackResponseMessage();
		exceptionHandleTemplate(new Callback<BranchTransactionRollbackRequestMessage, BranchTransactionRollbackResponseMessage>()
		{
			@Override
			public void execute(BranchTransactionRollbackRequestMessage branchTransactionRollbackRequestMessage, BranchTransactionRollbackResponseMessage branchTransactionRollbackResponseMessage) throws GlobalTransactionException
			{
				doBranchTransactionRollback(branchTransactionRollbackRequestMessage, branchTransactionRollbackResponseMessage);
			}
		}, branchTransactionRollbackRequestMessage, branchTransactionRollbackResponseMessage);
		return branchTransactionRollbackResponseMessage;
	}

	protected abstract void doBranchTransactionRollback(BranchTransactionRollbackRequestMessage branchTransactionRollbackRequestMessage, BranchTransactionRollbackResponseMessage branchTransactionRollbackResponseMessage) throws GlobalTransactionException;

	@Override
	public ResponseMessage onRequest(RpcContext rpcContext, RequestMessage request)
	{
		if (!(request instanceof BranchTransactionRequestMessage))
		{
			throw new IllegalArgumentException();
		}
		BranchTransactionRequestMessage branchTransactionRequestMessage = (BranchTransactionRequestMessage) request;
		branchTransactionRequestMessage.setRMInboundMessageHandler(this);
		return branchTransactionRequestMessage.handle(rpcContext);
	}

	@Override
	public void onResponse(RpcContext rpcContext, ResponseMessage response)
	{
		throw new ShouldNeverHappenException();

	}
}
